Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: OpenDoc Cookbook / Part - Appendixes
Appendix A - OpenDoc Utilities


QuickDraw Focus Library (FocusLib)

This section describes the utilities defined in the files FocusLib.h and FocusLib.cpp. These utilities are useful for setting up the drawing environment to render into a facet for Mac OS part editors using the classic QuickDraw imaging environment. Using QuickDraw GX is discussed in the recipe QuickDraw GX and OpenDoc.

What the Focus Library Does

The term focus, as used in the focus library, is only dimly related to the regular OpenDoc concept of a focus. The term comes from the Focus method in MacApp, which sets up QuickDraw to draw into a view.

Focusing does the following things:

Once your drawing environment is focused, you can start issuing QuickDraw commands (or doing higher level things that use QuickDraw) using your frame's coordinate system.

What the Focus Library Does Not Do

The focus library sets up the QuickDraw environment, so it cannot set up any kind of drawing state or transformations that QuickDraw does not understand. In particular, it does not handle any type of transformations other than offsets. If your facet ends up scaled, rotated, or skewed, the focus library helps you only with the offset portion of the transformation. You can do the rest of the transformation manually by transforming the coordinates of all points before you draw them.

Transformations other than scaling are particularly hard to handle in QuickDraw, which provides no native facilities for rotating text, bitmaps, or ellipses. QuickDraw GX handles all kinds of transformations automatically.

Using the Focus Library From C++

Using the focus library is easy. The usual way, for C++ clients, is to declare a CFocus object on the stack. When the object is constructed, the focusing takes place. When the object goes out of scope and is destroyed, the previous state of QuickDraw is restored. For example:

void DrawMyStuff( Environment *ev, ODFacet *facet ) {
CFocus foc(ev,facet);
MoveTo(0,0);
LineTo(100,100);
}
There are three variants of CFocus, described in the following sections.

CFocusWindow

The CFocusWindow class sets the window, not the facet's canvas, as the current graphics port. There is no difference, unless your facet is on an offscreen canvas. In that case, a regular CFocus would not cause the drawing to appear immediately on screen since it would first go into the offscreen canvas until the next update event. For interactive use such as rubber-banding a line or object while the mouse is down, use CFocusWindow to ensure that things are drawn immediately to the screen.

CFocusFrame

The CFocusFrame class does not take into account the frame's internal transformation. This means that (0,0) will be the top-left corner of the facet. This is useful when drawing frame adornments such as borders or scroll bars instead of the actual contents.

CFocusWindowFrame

The CFocusWindowFrame class is a combination of CFocusWindow and CFocusFrame.

The constructors of any of the CFocus classes take an optional extra parameter, which is a pointer to an ODShape object. If it is supplied, drawing is further clipped to the intersection of that shape and the facet's clip shape. This is useful when drawing into only part of the facet (as when handling a Draw method call).

Using the Focus Library From C

If you are using C, or do not use C++ features like constructors, you can explicitly call the BeginFocus and EndFocus functions. For example:

void DrawMyStuff( Environment *ev, ODFacet *facet ) {
FocusState state;
BeginFocus(ev,&state,facet,kODTrue,kODFalse,kODNULL);
MoveTo(0,0);
LineTo(100,100);
EndFocus(&state);        // Must explicitly end focusing!
}
You must declare a FocusState variable and then call BeginFocus, whose parameters look like this:

void BeginFocus( Environment *ev, FocusState*, ODFacet*,
   ODBoolean toContent, ODBoolean toWindow, ODShape *clipTo );
The toContent parameter determines whether to clip to the frame's content (as in CFocus) or to the frame border (as in CFocusFrame).

The toWindow parameter determines whether to draw directly into the window (as in CFocus) or into the facet's canvas (as in CFocusWindow).

The clipTo parameter, if not kODNULL, is an ODShape to which drawing is clipped.

IMPORTANT
It is important that you always call EndFocus after BeginFocus. If you don't, the drawing state is not restored and you will leak some memory. If you use exceptions, and anything between BeginFocus and EndFocus could throw an exception, you need to catch the exception and call EndFocus before re-raising it. (The C++ classes are based on the Destructo class, so they always clean up automatically.)

PostScript Printing

The focus library takes care of some tricky situations in PostScript(TM) printing. The LaserWriter driver does not handle QuickDraw Regions, so any attempt to clip to a nonrectangular area is ignored in the PostScript output. Not being able to clip to nonrectangular areas is a problem, since facets are often clipped to nonrectangular areas.

To work around this, the focus library includes two utility functions that emit some fancy PostScript code to set the clipping properly. If you are using the focus library calls described previously, these functions are called automatically and you don't need to worry about them. You need to know about these calls only if you do not want to use the rest of the focus library.

ODBeginPostScriptClip emits PostScript code to clip to the ODShape object passed in (in the coordinate system of the current graphics port). ODEndPostScriptClip ends the clipping. These functions will have no effect unless the current graphics port is in fact a printing port that is printing via the LaserWriter driver.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
16 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help